﻿; (function () {

    'use strict';

    window.GridModel = function GridModel() {
        /// <field  name='cells' type='Array' elementType="CellsCollection"></field>
        this.cells = [[]];

        /// <field  name='cells' type='Array' elementType="CellsCollection"></field>
        this.cellsByColumn = [[]];

        /// <field  name='cells' type='Array' elementType="CellsCollection"></field>
        this.cellsByRegion = [[]];
    }

    GridModel.revive = function (data) {
        var grid = new GridModel();

        for (var i = 0; i < 9; i++) {
            grid.cells[i] = [];
            for (var j = 0; j < 9; j++) {
                var cellData = {};
                cellData.content = data.cells[i][j];
                var cell = CellModel.revive(cellData);
                grid.cells[i][j] = cell;
                grid.cells[i][j] = cell;
            }
        }
        grid.updateIndex();
        return grid;
    }

    GridModel.prototype.toJSON = function () {
        var js = {}
        js._t = 'GridModel'

        var cellsData = [[]]
        for (var i = 0; i < 9; i++) {
            cellsData[i] = [];
            for (var j = 0; j < 9; j++) {
                var cellData = this.cells[i][j].toJSON();
                cellsData[i][j] = cellData.content;
            }
        }

        js.cells = cellsData;
        return js;
    };

    GridModel.prototype.copy = function (otherGrid) {
        if (this === otherGrid)
            return;
        for (var i = 0; i < 9; i++) {
            for (var j = 0; j < 9; j++) {
                this.cells[i][j].copy(otherGrid.cells[i][j]);
            }
        }
    }

    GridModel.prototype.updateIndex = function () {
        this.updateCellsIndex();
        this.updateUnitsIndex();
    }

    GridModel.prototype.updateCellsIndex = function () {
        for (var i = 0; i < 9; i++) {
            for (var j = 0; j < 9; j++) {
                this.cells[i][j].indices = { i: i, j: j };
            }
        }
    }

    GridModel.prototype.updateUnitsIndex = function () {

        // update by column
        for (var j = 0; j < 9; j++) {
            this.cellsByColumn[j] = [];
            for (var i = 0; i < 9; i++) {
                this.cellsByColumn[j][i] = this.cells[i][j];
            }
        }

        // update by region
        this.cellsByRegion = [[]];
        for (var i = 0; i < 9; i++) {
            for (var j = 0; j < 9; j++) {
                var regionId = RegionHelper.computedRegions[i][j];

                if (!this.cellsByRegion[regionId])
                    this.cellsByRegion[regionId] = [];

                this.cellsByRegion[regionId].push(this.cells[i][j]);
            }
        }
    }

    GridModel.prototype.getBaseGrid = function () {
        var grid = new GridModel();

        for (var i = 0; i < 9; i++) {
            grid.cells[i] = [];
            for (var j = 0; j < 9; j++) {
                var originalCell = this.cells[i][j];
                var cell = new CellModel();
                grid.cells[i][j] = cell;

                if (originalCell.isBase) {
                    cell.isBase = true;
                    cell.value = originalCell.value;
                }
            }
        }

        grid.updateIndex();
        return grid;
    }

    GridModel.prototype.getCell = function (indices) {
        return this.cells[indices.i][indices.j];
    }

    GridModel.prototype.isFull = function () {
        // console.log('r');
        for (var i = 0; i < 9; i++) {
            for (var j = 0; j < 9; j++) {
                var cell = this.cells[i][j];
                if (cell.value === 0)
                    return false;
            }
        }

        return true;
    }

    GridModel.fromShortString = function (strSingles) {
        var grid = new GridModel();
        var k = 0;
        for (var i = 0; i < 9; i++) {
            grid.cells[i] = [];
            for (var j = 0; j < 9; j++) {
                var cell = new CellModel();
                grid.cells[i][j] = cell;

                var car = strSingles.charAt(k);
                if (car != '-' && car != '.' && car != '0') {
                    cell.value = parseInt(car) | 0;
                    cell.isBase = true;
                }

                k++;
            }
        }
        grid.updateIndex();
        return grid;
    }

    GridModel.prototype.toShortString = function (sep) {

        var output = "";
        sep = sep || '-';
        for (var i = 0; i < 9; i++) {
            for (var j = 0; j < 9; j++) {
                var cell = this.cells[i][j];
                if (cell.value === 0) output += sep;
                else output += cell.value;
            }
        }

        return output;
    }

}(window));